package com.itcam.tingshu.album.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itcam.tingshu.album.config.VodConstantProperties;
import com.itcam.tingshu.album.mapper.AlbumInfoMapper;
import com.itcam.tingshu.album.mapper.TrackInfoMapper;
import com.itcam.tingshu.album.mapper.TrackStatMapper;
import com.itcam.tingshu.album.service.AlbumInfoService;
import com.itcam.tingshu.album.service.TrackInfoService;
import com.itcam.tingshu.album.service.VodService;
import com.itcam.tingshu.common.constant.SystemConstant;
import com.itcam.tingshu.common.execption.ItcamException;
import com.itcam.tingshu.common.result.Result;
import com.itcam.tingshu.common.result.ResultCodeEnum;
import com.itcam.tingshu.common.util.AuthContextHolder;
import com.itcam.tingshu.common.util.UploadFileUtil;
import com.itcam.tingshu.model.album.AlbumInfo;
import com.itcam.tingshu.model.album.TrackInfo;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itcam.tingshu.model.album.TrackStat;
import com.itcam.tingshu.user.client.UserInfoFeignClient;
import com.itcam.tingshu.user.client.UserListenProcessFeignClient;
import com.itcam.tingshu.vo.album.AlbumTrackListVo;
import com.itcam.tingshu.vo.album.TrackInfoVo;
import com.itcam.tingshu.vo.album.TrackMediaInfoVo;
import com.itcam.tingshu.vo.user.UserInfoVo;
import com.qcloud.vod.VodUploadClient;
import com.qcloud.vod.model.VodUploadRequest;
import com.qcloud.vod.model.VodUploadResponse;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.validator.internal.constraintvalidators.bv.time.futureorpresent.FutureOrPresentValidatorForReadableInstant;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
@SuppressWarnings({"unchecked", "rawtypes"})
public class TrackInfoServiceImpl extends ServiceImpl<TrackInfoMapper, TrackInfo> implements TrackInfoService {

    @Autowired
    private TrackInfoMapper trackInfoMapper;

    @Autowired
    private VodConstantProperties vodConstantProperties;

    @Autowired
    private TrackStatMapper trackStatMapper;

    @Autowired
    private AlbumInfoMapper albumInfoMapper;

    @Autowired
    private VodService vodService;

    @Autowired
    private UserInfoFeignClient userInfoFeignClient;

    @Autowired
    private AlbumInfoService albumInfoService;

    @Autowired
    private UserListenProcessFeignClient userListenProcessFeignClient;

    /**
     * 上传声音
     * @param file
     * @return
     */
    @Override
    public Map<String, Object> uploadTrack(MultipartFile file) {
        //  创建map集合
        Map<String, Object> map = new HashMap<>();
        //  获取路径
        String tempPaht = UploadFileUtil.uploadTempPath(vodConstantProperties.getTempPath(), file);
        //  初始化一个上传客户端对象
        VodUploadClient vodUploadClient = new VodUploadClient(vodConstantProperties.getSecretId(), vodConstantProperties.getSecretKey());
        //  获取上传请求对象
        VodUploadRequest request = new VodUploadRequest();
        request.setMediaFilePath(tempPaht);
        //  云点播：不指定任务流不花钱; 指定就要花钱，存储也花钱。
        //  封面，任务流，存储地域，指定分片并发数
        //  request.setProcedure("Your Procedure Name");
        //  调用上传方法
        try {
            VodUploadResponse response = vodUploadClient.upload(vodConstantProperties.getRegion(), request);
            log.info("Upload FileId = {}", response.getFileId());
            map.put("mediaFileId", response.getFileId());
            map.put("mediaUrl", response.getMediaUrl());
            //  返回集合
            return map;
        } catch (Exception e) {
            // 业务方进行异常处理
            log.error("Upload Err", e);
            throw new ItcamException(ResultCodeEnum.FAIL);
        }
    }

    /**
     * 保存声音
     * @param trackInfoVo
     * @param userId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveTrackInfo(TrackInfoVo trackInfoVo, Long userId) {
        // track_info 声音主表
        // 属性拷贝
        TrackInfo trackInfo = new TrackInfo();
        BeanUtils.copyProperties(trackInfoVo, trackInfo);
        trackInfo.setUserId(userId);

        // track_info.order_num 表示声音的顺序号, 必须是同一张专辑
        // select order_num from track_info where album_id = ? and is_deleted = 0 order by id desc limit 1;
        // 获取查询结果
        // TrackInfo trackInfoQuery = trackInfoMapper.selectList(queryWrapper).get(0);
        TrackInfo trackInfoQuery = trackInfoMapper.selectOne(new LambdaQueryWrapper<TrackInfo>() // 为什么是selectOne？——因为执行完之后只返回一条结果集
                .eq(TrackInfo::getAlbumId, trackInfoVo.getAlbumId())
                .orderByDesc(TrackInfo::getId) // 根据id倒叙
                .last("limit 1") //
                .select(TrackInfo::getOrderNum)); // 查询一个字段

        // 判断查询对象是否为空
        // 将以下代码使用三元运算符表示
        //        if (trackInfoQuery == null) {
        //            trackInfo.setOrderNum(1);
        //        } else {
        //            (trackInfoQuery.getOrderNum() + 1);
        //        }
        trackInfo.setOrderNum(trackInfoQuery == null ? 1 : trackInfoQuery.getOrderNum() + 1);

        // media_duration media_file_id media_url media_size media_type 需要通过 media_file_id 从云点播获取
        // 调用云点播的方法
        TrackMediaInfoVo trackMediaInfoVo = vodService.getMediaInfo(trackInfoVo.getMediaFileId());
        trackInfo.setMediaSize(trackMediaInfoVo.getSize());
        trackInfo.setMediaDuration(trackMediaInfoVo.getDuration());
        trackInfo.setMediaType(trackMediaInfoVo.getType());
        trackInfo.setMediaUrl(trackMediaInfoVo.getMediaUrl());

        // 保存数据
        // track_stat(声音统计表)
        this.saveTrackStat(trackInfo.getId(), SystemConstant.TRACK_STAT_PLAY);
        this.saveTrackStat(trackInfo.getId(), SystemConstant.TRACK_STAT_COLLECT);
        this.saveTrackStat(trackInfo.getId(), SystemConstant.TRACK_STAT_PRAISE);
        this.saveTrackStat(trackInfo.getId(), SystemConstant.TRACK_STAT_COMMENT);

        // 声明专辑对象
        AlbumInfo albumInfo = albumInfoMapper.selectById(trackInfoVo.getAlbumId());
        albumInfo.setIncludeTrackCount(albumInfo.getIncludeTrackCount() + 1);
        // 修改专辑表中的include_track_count数据
        albumInfoMapper.updateById(albumInfo);
    }

    /**
     * 删除声音
     * @param trackId
     */
    @Override
    public void removeTrackInfo(Long trackId) {
        // 根据专辑Id 获取专辑对象
        TrackInfo trackInfo = trackInfoMapper.selectById(trackId);
        AlbumInfo albumInfo = albumInfoMapper.selectById(trackInfo.getAlbumId());

        // 删除 track_info track_stat album_info.include_track_count
        // is_deleted = 1 代表无效数据
        this.trackInfoMapper.deleteById(trackId);
        trackStatMapper.delete(new LambdaQueryWrapper<TrackStat>()
                .eq(TrackStat::getTrackId, trackId));

        // 更新album_info.include_track_count 字段
        // album_info.include_track_count = album_info.include_track_count - 1
        // 删除一个专辑得知道专辑总数是多少然后-1就可以了
        albumInfo.setIncludeTrackCount(albumInfo.getIncludeTrackCount());
        albumInfoMapper.updateById(albumInfo);

        // 更新序号只需要处理order_num一个字段就可以了。
        // update track_info set order_num = order_num - 1 where order_num > 52  and album_id = 1 and is_deleted = 0;
        trackInfoMapper.updateOrderNum(trackInfo.getOrderNum(), trackInfo.getAlbumId());

        // 流媒体的声音删除
        vodService.deleteMedia(trackInfo.getMediaFileId());
    }

    /**
     * 根据声音Id获取声音对象
     * @param trackId
     * @return
     */
    @Override
    public TrackInfo getTrackInfo(Long trackId) {
        // 获取声音对象
        TrackInfo trackInfo = trackInfoMapper.selectById(trackId);
        // 返回数据
        return trackInfo;
    }

    /**
     * 修改声音
     * @param trackId
     * @param trackInfoVo
     */
    @Override
    public void updateTrackInfo(Long trackId, TrackInfoVo trackInfoVo) {
        // 没有声音修改：直接修改trackInfo; 如果有声音修改，改变声音大小，类型等数据
        // TrackInfo trackInfo = new TrackInfo(); trackInfo.getAlbumId();
        // 1.创建TrackInfo对象 this.getById(trackId); = ServicelImpl.getById(id)
        TrackInfo trackInfo = this.getById(trackId);

        // 2.先查询声音Id
        String mediaFileId = trackInfo.getMediaFileId();

        // 3.进行属性拷贝
        BeanUtils.copyProperties(trackInfoVo, trackInfo);

        // 4.根据 原有声音Id 与 新的声音Id 是否相等，判断是否对声音做了修改
        // 声明对象的 trackInfo.getMediaFileId() 可能会产生空指针，如何解决 从数据库中获取即可 将TrackInfo trackInfo = new TrackInfo();改为TrackInfo trackInfo = this.getById(trackId);
        if (!trackInfoVo.getMediaFileId().equals(mediaFileId)) {
            // 声音修改了：改变声音大小，类型等数据 --> 从云点播平台获取声音对象
            TrackMediaInfoVo trackMediaInfoVo = vodService.getMediaInfo(trackInfoVo.getMediaFileId());
            trackInfo.setMediaDuration(trackMediaInfoVo.getDuration());
            trackInfo.setMediaSize(trackMediaInfoVo.getSize());
            trackInfo.setMediaType(trackMediaInfoVo.getType());
            trackInfo.setMediaUrl(trackMediaInfoVo.getMediaUrl());
            // 删除云点播的声音记录
            vodService.deleteMedia(mediaFileId);
        }
        // 修改表数据
        trackInfoMapper.updateById(trackInfo);
    }

    /**
     * 根据专辑Id获取声音分页列表
     * @param albumTrackListVoPage
     * @param albumId
     * @param userId
     * @return
     */
    @Override
    public IPage<AlbumTrackListVo> findAlbumTrackPage(Page<AlbumTrackListVo> albumTrackListVoPage, Long albumId, Long userId) {
        // 复杂的业务逻辑，根据专辑Id获取到声音列表
        IPage<AlbumTrackListVo> pageInfo = trackInfoMapper.selectAlbumTrackPage(albumTrackListVoPage, albumId);
        // 获取专辑对象
        AlbumInfo albumInfo = this.albumInfoMapper.selectById(albumId);
        // 判断是否登录
        if (null == userId) {
            // 当前未登录，专辑类型分为 0101-免费，0201-vip免费，0103-付费

            // 判断专辑类型
            if (!albumInfo.getPayType().equals(SystemConstant.ALBUM_PAY_TYPE_FREE)) {
                // 0102-vip免费，0103-付费 除免费试听集数以外都需要显示付费标识
                // 获取当前专辑对应的免费集数
                Integer tracksForFree = albumInfo.getTracksForFree();
                // 10条前五
                // select*from track_info track where album_id=1429 and is_deleted=0 and order_num<=5
                pageInfo.getRecords().stream()
                        .filter(albumTrackListVo -> albumTrackListVo.getOrderNum() > tracksForFree)
                        .forEach(albumTrackListVo -> albumTrackListVo.setIsShowPaidMark(true));
                // 返回数据
                return pageInfo;
            }
        } else {
            // 声明一个变量表示是否需要付费
            boolean isNeedPaid = false;
            // 当前处于登录状态,专辑的类型 0102-vip免费，0103-付费
            // 通过userId，获取用户身份
            Result<UserInfoVo> userInfoVoResult = userInfoFeignClient.getUserInfoVo(userId);
            Assert.notNull(userInfoVoResult, "用户结果集为空");
            UserInfoVo userInfoVo = userInfoVoResult.getData();
            Assert.notNull(userInfoVo, "用户对象为空");

            if (albumInfo.getPayType().equals(SystemConstant.ALBUM_PAY_TYPE_VIPFREE)) {
                // 0102-vip免费 —— 判断当前这个用户是否为vip
                if ((userInfoVo.getIsVip() == 1 && userInfoVo.getVipExpireTime().before(new Date())) || userInfoVo.getIsVip() == 0) {
                    // 需要付费
                    isNeedPaid = true;
                }
            } else if (albumInfo.getPayType().equals(SystemConstant.ALBUM_PAY_TYPE_REQUIRE)) {
                // 0103-付费
                isNeedPaid = true;
            }

            // 统一处理付费
            if (isNeedPaid) {
                // 获取需要付费的声音id列表
                List<AlbumTrackListVo> albumTrackNeedPaidListVoList = pageInfo.getRecords().stream()
                        .filter(albumTrackListVo -> albumTrackListVo.getOrderNum() > albumInfo.getTracksForFree())
                        .collect(Collectors.toList());
                // 获取对应声音的id列表
                List<Long> trackIdList = albumTrackNeedPaidListVoList.stream()
                        .map(AlbumTrackListVo::getTrackId)
                        .collect(Collectors.toList());
                // 远程调用订单服务，判断当前用户是否购买过专辑，或者购买过声音
                // map中的key=trackId，value=0/1   0 表示付费 - true，1 表示免费 - false
                Result<Map<Long, Integer>> mapResult = userInfoFeignClient.userIsPaidTrack(userId, trackIdList);
                Assert.notNull(mapResult, "返回结果集为空");
                Map<Long, Integer> map = mapResult.getData();
                // 循环遍历集合
                for (AlbumTrackListVo albumTrackListVo : albumTrackNeedPaidListVoList) {
                    // 赋值数据
                    albumTrackListVo.setIsShowPaidMark(map.get(albumTrackListVo.getTrackId()) == 1 ? false : true);
                }
            }
        }
        // 返回数据
        return pageInfo;
    }

    // 播放声音 -- 单独测试 👇

    /**
     * 播放声音
     * @param userId
     * @param trackId
     * @return
     */
    @Override
    public Map<String, Object> getPlayToken(Long userId, Long trackId) {
        TrackInfo trackInfo = this.getById(trackId);
        Assert.notNull(trackInfo, "声音对象不能为空");
        AlbumInfo albumInfo = albumInfoService.getById(trackInfo.getAlbumId());
        Assert.notNull(trackInfo, "专辑对象不能为空");
        //	判断用户是否需要付费
        if (null == userId) {
            //	除免费的都需要显示付费标识
            if (!SystemConstant.ALBUM_PAY_TYPE_FREE.equals(albumInfo.getPayType()) && trackInfo.getOrderNum().intValue() > albumInfo.getTracksForFree().intValue()) {
                throw new ItcamException(ResultCodeEnum.NO_BUY_NOT_SEE);
            }
        } else {
            boolean isNeedPiad = false;
            if (SystemConstant.ALBUM_PAY_TYPE_VIPFREE.equals(albumInfo.getPayType())) {
                //获取用户信息
                Result<UserInfoVo> userInfoVoResult = userInfoFeignClient.getUserInfoVo(userId);
                Assert.notNull(userInfoVoResult, "用户对象不能为空");
                UserInfoVo userInfoVo = userInfoVoResult.getData();

                //1，VIP免费（非VIP观看）
                if (userInfoVo.getIsVip().intValue() == 0) {
                    isNeedPiad = true;
                }
                //1.1 如果是vip但是vip过期了（定时任务还为更新状态）
                if (userInfoVo.getIsVip().intValue() == 1 && userInfoVo.getVipExpireTime().before(new Date())) {
                    isNeedPiad = true;
                }
            } else if (SystemConstant.ALBUM_PAY_TYPE_REQUIRE.equals(albumInfo.getPayType())) {
                //2，付费类型的
                isNeedPiad = true;
            }
            //需要付费，判断用户是否购买过专辑或声音
            if (isNeedPiad) {
                //	处理试听声音，判断当前声音是否包含在免费试听范围
                if (trackInfo.getOrderNum().intValue() > albumInfo.getTracksForFree().intValue()) {
                    //判断用户是否购买该声音
                    List<Long> tarckIdList = Arrays.asList(trackId);
                    Result<Map<Long, Integer>> mapResult = userInfoFeignClient.userIsPaidTrack(albumInfo.getId(), tarckIdList);
                    Assert.notNull(mapResult, "map 集合不能为空");
                    Map<Long, Integer> map = mapResult.getData();
                    // 未购买
                    if (map.get(trackId) == 0) {
                        throw new ItcamException(ResultCodeEnum.NO_BUY_NOT_SEE);
                    }
                }
            }
        }
        Result<BigDecimal> result = this.userListenProcessFeignClient.getTrackBreakSecond(trackId);
        Assert.notNull(result, "获取到跳出时间结果不能为空");
        BigDecimal breakSecond = result.getData();
        // 获取到播放token
        String playToken = vodService.getPlayToken(trackInfo.getMediaFileId());
        Map<String, Object> map = new HashMap<>();
        map.put("playToken", playToken);
        map.put("mediaFileId", trackInfo.getMediaFileId());
        map.put("breakSecond", breakSecond);
        map.put("appId", vodConstantProperties.getAppId());

        //   获取下一个播放声音
        //   select id from track_info where album_id = ? and orderNum = ? order by order_num limit 1
        TrackInfo nextTrackInfo = this.getOne(
                new LambdaQueryWrapper<TrackInfo>()
                        .eq(TrackInfo::getAlbumId, trackInfo.getAlbumId())
                        .gt(TrackInfo::getOrderNum, trackInfo.getOrderNum())
                        .orderByDesc(TrackInfo::getOrderNum)
                        .select(TrackInfo::getId)
                        .last("limit 1")
        );
        if (null != nextTrackInfo) {
            map.put("nextTrackInfo", nextTrackInfo.getId());
        } else {
            map.put("nextTrackInfo", 0L);
        }
        return map;
    }

    /**
     * 获取用户声音分集购买支付列表
     * @param trackId
     * @return
     */
    @Override
    public List<Map<String, Object>> findUserTrackPaidList(Long trackId, Long userId) {
        /*
            mybatis-plus 中的一些比较符号含义
                lt：less than 小于
                le：less than or equal to 小于等于
                eq：equal to 等于
                ne：not equal to 不等于
                ge：greater than or equal to 大于等于
                gt：greater than 大于
         */
        // 1. 先根据专辑Id{用户Id}获取到专辑对应用户已购买声音Id集合列表
        // 根据声音Id获取到当前声音对象
        TrackInfo trackInfo = this.getById(trackId);
        // 获取专辑对象，后续为了获取专辑对应单条声音的价格
        AlbumInfo albumInfo = this.albumInfoMapper.selectById(trackInfo.getAlbumId());
        // 远程调用 —— 用户购买过当前专辑所对应的声音Id集合列表 19 20
        Result<List<Long>> trackIdListResult = this.userInfoFeignClient.findUserPaidTrackList(trackInfo.getAlbumId());
        // 判断
        Assert.notNull(trackIdListResult, "声音Id集合列表为空");
        List<Long> trackIdList = trackIdListResult.getData();
        Assert.notNull(trackIdList, "声音Id集合为空");

        // 2. 获取到当前专辑{albumId}中大于{orderNum}当前声音Id的集合列表
        // select * from track_info where album_id = 341 and order_num > 7;
        // 所有的声音Id集合列表 8-54
        List<TrackInfo> trackInfoList = trackInfoMapper.selectList(new LambdaQueryWrapper<TrackInfo>()
                .eq(TrackInfo::getAlbumId, trackInfo.getAlbumId())
                .gt(TrackInfo::getOrderNum, trackInfo.getOrderNum()));

        // 3. 获取到当前要支付的声音Id 列表{ 2 与 1 做一个排除即可 }
        // 集数排查：获取差集：1.双重for 2.stream()流
        List<TrackInfo> infoList = trackInfoList.stream().filter(track -> {
            // 过滤
            return !trackIdList.contains(track.getId());
        }).collect(Collectors.toList());

        // 4. 构造声音分集购买列表
        BigDecimal trackPrice = albumInfo.getPrice();
        int size = infoList.size();
        // 声明集合对象
        List<Map<String, Object>> list = new ArrayList<>();
        // 知道当前你有多少个声音需要付费
        // 判断什么时候购买本机，后10集，后20集，后23集
        // 添加本集信息
        if (size >= 0) {
            // 声明map集合
            Map<String, Object> map = new HashMap<>();
            map.put("name", "本集");
            // 单条声音的价格是多少？根据专辑Id获取到专辑对象
            map.put("price", trackPrice);
            map.put("trackCount", 0);
            // 将本集信息添加到集合中
            list.add(map);
        }
        // // 后0-9集【后n集】
        // if (infoList.size() >= 0 && infoList.size() < 10) {
        //     // 声明map集合
        //     Map<String, Object> map = new HashMap<>();
        //     map.put("name", "后" + infoList.size() + "集");
        //     // 单条声音的价格是多少？根据专辑Id获取到专辑对象
        //     // BigDecimal数据类型时，传递参数的时候，参数需要使用String数据类型，防止精度损失
        //     map.put("price", albumInfo.getPrice().multiply(new BigDecimal(String.valueOf(infoList))));
        //     map.put("trackCount", infoList.size());
        //     // 将本集信息添加到集合中
        //     list.add(map);
        // }
        // // 后10集
        // if (infoList.size() > 10) {
        //     // 声明map集合
        //     Map<String, Object> map = new HashMap<>();
        //     map.put("name", "后10集");
        //     // 单条声音的价格是多少？根据专辑Id获取到专辑对象
        //     // BigDecimal数据类型时，传递参数的时候，参数需要使用String数据类型，防止精度损失
        //     map.put("price", albumInfo.getPrice().multiply(new BigDecimal("10")));
        //     map.put("trackCount", 10);
        //     // 将本集信息添加到集合中
        //     list.add(map);
        // }
        // // 10到20与超过20集
        // if (infoList.size() >= 10 && infoList.size() < 20) {
        //     // 声明map集合
        //     Map<String, Object> map = new HashMap<>();
        //     map.put("name", "后" + infoList.size() + "集");
        //     // 单条声音的价格是多少？根据专辑Id获取到专辑对象
        //     // BigDecimal数据类型时，传递参数的时候，参数需要使用String数据类型，防止精度损失
        //     map.put("price", albumInfo.getPrice().multiply(new BigDecimal("10")));
        //     map.put("trackCount", infoList.size());
        //     // 将本集信息添加到集合中
        //     list.add(map);
        // }
        // // 后20集
        // if (infoList.size() > 20) {
        //     // 声明map集合
        //     Map<String, Object> map = new HashMap<>();
        //     map.put("name", "后20集");
        //     // 单条声音的价格是多少？根据专辑Id获取到专辑对象
        //     // BigDecimal数据类型时，传递参数的时候，参数需要使用String数据类型，防止精度损失
        //     map.put("price", albumInfo.getPrice().multiply(new BigDecimal("20")));
        //     map.put("trackCount", 20);
        //     // 将本集信息添加到集合中
        //     list.add(map);
        // }
        // // 20到30与超过30集
        // if(infoList.size() > 20 && infoList.size() <= 30) {
        //     Map<String, Object> map = new HashMap<>();
        //     int count = infoList.size();
        //     BigDecimal price = albumInfo.getPrice().multiply(new BigDecimal(count));
        //     map.put("name", "后"+count+"集");
        //     map.put("price", price);
        //     map.put("trackCount", count);
        //     list.add(map);
        // }
        // // 后30集
        // if(infoList.size() > 30) {
        //     Map<String, Object> map = new HashMap<>();
        //     BigDecimal price = albumInfo.getPrice().multiply(new BigDecimal(30));
        //     map.put("name", "后30集");
        //     map.put("price", price);
        //     map.put("trackCount", 30);
        //     list.add(map);
        // }
        // // 后50集
        // if(infoList.size() > 30 && infoList.size() <= 50) {
        //     Map<String, Object> map = new HashMap<>();
        //     int count = infoList.size();
        //     BigDecimal price = albumInfo.getPrice().multiply(new BigDecimal(count));
        //     map.put("name", "后"+count+"集");
        //     map.put("price", price);
        //     map.put("trackCount", count);
        //     list.add(map);
        // }
        // // 最多能购买50集
        // if(infoList.size() > 50) {
        //     Map<String, Object> map = new HashMap<>();
        //     BigDecimal price = albumInfo.getPrice().multiply(new BigDecimal(50));
        //     map.put("name", "后50集");
        //     map.put("price", price);
        //     map.put("trackCount", 50);
        //     list.add(map);
        // }

        // 根据不同集数条件添加相应的信息
        if (size > 0 && size <= 50) {
            int[] thresholds = {10, 20, 30, 50};
            for (int threshold : thresholds) {
                if (size < threshold) {
                    Map<String, Object> map = new HashMap<>();
                    map.put("name", "后" + threshold + "集");
                    map.put("price", albumInfo.getPrice().multiply(new BigDecimal(String.valueOf(threshold))));
                    map.put("trackCount", threshold);
                    list.add(map);
                } else {
                    Map<String, Object> map = new HashMap<>();
                    map.put("name", "后" + size + "集");
                    map.put("price", trackPrice.multiply(new BigDecimal(String.valueOf(size))));
                    map.put("trackCount", size);
                    list.add(map);
                    break;
                }
            }
        }

        // 返回数据
        return list;
    }

    /**
     * 批量获取下单付费声音列表
     * @param trackId
     * @param trackCount
     * @return
     */
    @Override
    public List<TrackInfo> findPaidTrackInfoList(Long trackId, Integer trackCount) {
        /*
            1. 根据声音Id 获取到当前声音对象
            2. 获取已支付的声音Id 列表
            3. 判断购买声音的声音集数是否大于0
               1. 大于0
               2. 查询当前专辑、并且 大于当前声音顺序号的声音、并且要按照序号进行升序排序 ，如果有已支付的声音Id，
                    一定要除去已购买的声音Id 列表 并添加到返回的集合列表中，同时还要添加限制购买几条声音的条件。
               3. 等于0
                   1. 将查询的对象直接添加到的集合列表中
         */
        // 创建对象
        List<TrackInfo> trackInfoList = new ArrayList<>();
        // 根据当前声音Id获取到声音对象
        TrackInfo trackInfo = this.getById(trackId);
        // 调用方法获取用户已购买的声音列表
        Result<List<Long>> userPaidTrackList = this.userInfoFeignClient.findUserPaidTrackList(trackInfo.getAlbumId());
        Assert.notNull(userPaidTrackList, "声音Id集合列表为空");
        List<Long> traackIdList = userPaidTrackList.getData();
        Assert.notNull(traackIdList, "声音Id集合为空");
        // 查询用户购买的声音列表
        if (trackCount > 0) {
            // select * from track_info where album_id=1451 and order_num > 6 and order_num not in (9,10) limit 10;
            LambdaQueryWrapper<TrackInfo> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(TrackInfo::getAlbumId, trackInfo.getAlbumId()).gt(TrackInfo::getOrderNum, trackInfo.getOrderNum());
            // 购买声音Id可能存在也可能不存在
            if (CollectionUtils.isEmpty(traackIdList)) {
                wrapper.notIn(TrackInfo::getId, traackIdList);
            }
            wrapper.last("limit " + trackCount);
            // 查询数据
            trackInfoList = trackInfoMapper.selectList(wrapper);
        } else {
            // 购买本集
            trackInfoList.add(trackInfo);
        }
        return trackInfoList;
    }

    // -------------------------------------------------------------------------------------------------------------------
    public void saveTrackStat(Long trackId, String statPlay) {
        // 保存声音统计数据
        TrackStat trackStat = new TrackStat();
        trackStat.setTrackId(trackId);
        trackStat.setStatType(statPlay);
        trackStat.setStatNum(0);
        trackStatMapper.insert(trackStat);
    }
}
